<template>
  <main class="x6editor">
    <!-- 图元区 -->
    <div id="experimentStencil" class="sider">
      <ItemPanel />
    </div>
    <section class="panel">
      <!-- 上边命令栏 -->
      <div class="top-toolbar">
        <TopToolbar />
      </div>
      <!-- 中间编辑区 -->
      <div class="graphWrapper">
        <div id="graphContainer"></div>
      </div>
      <div id="minimap"></div>
      <!-- 下边命令栏 -->
      <div class="bottom-toolbar">
        <BottomToolbar />
      </div>
    </section>
    <el-dialog
      title="提示"
      :visible.sync="ParamsDialogVisible"
    >
      <input type="text" v-model="doubleClickNode.data.args.title">
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </main>
</template>

<script>
import TopToolbar from './TopToolbar'
import BottomToolbar from './BottomToolbar'
import ItemPanel from './ItemPanel'
import { X6Editor } from './graph'
import EventBus from './EventBus'
import BusEvents from './EventBus/events'

export default {
  name: 'X6Editor',
  components: {
    TopToolbar,
    BottomToolbar,
    ItemPanel
  },
  data() {
    return {
      graph: null,
      dnd: null,
      stencil: null,
      doubleClickNode: {data: {args: {}}},
      ParamsDialogVisible: false
    }
  },
  mounted() {
    this.init()


    const rect = this.graph.addNode({
      x: 160,
      y: 30,
      shape: 'model-rect',

      label: 'SQL',

      data: {
        args: {
          title: 'SQL1'
        }
      },

      ports: {
        items: [
          {
            id: 'port1',
            group: 'in',
            attrs: {
              text: {
                text: 'port1',
              },
            },
          },
          {
            id: 'port2',
            group: 'in',
            attrs: {
              text: {
                text: 'port2',
              },
            },
          },
          {
            id: 'port3',
            group: 'in',
            attrs: {
              text: {
                text: 'port3',
              },
            },
          },
          {
            id: 'port4',
            group: 'out',
            attrs: {
              text: {
                text: 'port4',
              },
            },
          },
          {
            id: 'port5',
            group: 'out',
            attrs: {
              text: {
                text: 'port5',
              },
            },
          },
        ],
      },
    })

    this.graph.centerContent()
  },
  methods: {
    init() {
      const container = document.querySelector('.graphWrapper')
      const stencilContainer = document.getElementById('experimentStencil')
      const minimapContainer = document.getElementById('minimap')
      // TODO：在 X6Editor 中初始化好一切事务即可
      const x6editor = new X6Editor(container, stencilContainer, minimapContainer)
      // 获取到 x6editor 实例中的 graph 对象，方便后期处理其他业务
      this.graph = x6editor.graph
      this.dnd = x6editor.dnd

      this.onListenEventBus()
    },
    onListenEventBus() {
      // 节点双击事件监听
      EventBus.$on(BusEvents.NodeDBLCLick, ({ node }) => {
        this.doubleClickNode = node
        this.ParamsDialogVisible = true
      })
      // Command命令事件监听
      // undo
      EventBus.$on(BusEvents.CommandUndo, () => {
        const { graph } = this
        graph.history.undo()
        graph.cleanSelection()
      })
      // redo
      EventBus.$on(BusEvents.CommandRedo, () => {
        const { graph } = this
        graph.history.redo()
        graph.cleanSelection()
      })
      // copy
      EventBus.$on(BusEvents.CommandCopy, () => {
        const { graph } = this
        const cells = graph.getSelectedCells()
        if (cells.length) {
          graph.copy(cells)
        }
      })
      // cut
      EventBus.$on(BusEvents.CommandCut, () => {
        const { graph } = this
        const cells = graph.getSelectedCells()
        if (cells.length) {
          graph.cut(cells)
        }
      })
      // paste
      EventBus.$on(BusEvents.CommandPaste, () => {
        const { graph } = this
        if (!graph.isClipboardEmpty()) {
          const cells = graph.paste({ offset: 32 })
          graph.cleanSelection()
          graph.select(cells)
        }
      })
      // delete
      EventBus.$on(BusEvents.CommandDelete, () => {
        const { graph } = this
        const cells = graph.getSelectedCells()
        if (cells.length) {
          graph.removeCells(cells)
        }
      })
      // print
      EventBus.$on(BusEvents.CommandPrint, () => {
        const { graph } = this
        console.log(graph.toJSON())
      })
      // drag
      EventBus.$on(BusEvents.ItemDrag, ({ node, e }) => {
        this.dnd.start(node, e)
      })
    }
  }
}
</script>

<style lang="less">
.x6editor {
  width: calc(100vw - 8px);
  height: calc(100vh - 4px);
  box-sizing: border-box;

  display: flex;
  flex-direction: row;

  .sider {
    width: 300px;
    height: 100%;
    // 必须要这一句，否则Stencil很奇怪
    position: relative;
    // background-color: #f0f0f0;
    background-color: #f7f9fb;
    // border-radius: 10px;
  }

  .panel {
    flex-grow: 1;
    height: 100%;

    display: flex;
    flex-direction: column;

    .top-toolbar {
      width: 100%;
      height: 40px;
      background-color: #f7f9fb;
    }

    .graphWrapper {
      width: 100%;
      flex-grow: 1;
    }

    #minimap {
      width: 240px;
      height: 160px;
      position: absolute;
      right: 20px;
      bottom: 64px;
      background-color: greenyellow;
    }

    .bottom-toolbar {
      width: 100%;
      height: 40px;
      background-color: #ffffff;
    }
  }
}

.x6-port-body {
  visibility: hidden;
}
.x6-port-label {
  visibility: hidden;
}
</style>
